const padTwoDigits = value => (value < 10 ? `0${value}` : `${value}`);

const getCurrentDateString = () => {
  const now = new Date();
  const year = now.getFullYear();
  const month = padTwoDigits(now.getMonth() + 1);
  const day = padTwoDigits(now.getDate());
  return `${year}-${month}-${day}`;
};

const getCurrentTimeString = () => {
  const now = new Date();
  const hour = padTwoDigits(now.getHours());
  const minute = padTwoDigits(now.getMinutes());
  return `${hour}:${minute}`;
};

const combineDateTime = (datePart, timePart) => {
  if (!datePart || timePart === undefined || timePart === null || timePart === "") {
    return "";
  }
  return `${datePart} ${timePart}`;
};

const callCloud = options => {
  const app = (typeof getApp === "function") ? getApp() : null;
  if (app && typeof app.callCloudFunction === "function") {
    return app.callCloudFunction(options);
  }
  const { loadingTitle, ...rest } = options || {};
  const title =
    typeof loadingTitle === "string" && loadingTitle.trim()
      ? loadingTitle.trim()
      : "加载中...";
  wx.showLoading({ title, mask: true });
  const originalComplete = rest.complete;
  rest.complete = (...args) => {
    wx.hideLoading();
    if (typeof originalComplete === "function") {
      originalComplete(...args);
    }
  };
  return wx.cloud.callFunction(rest);
};

const toISOStringString = value => {
  if (!value) return "";

  const [datePart, timePart = "00:00"] = value.split(" ");
  const [year, month, day] = (datePart || "").split("-").map(Number);
  const [hour, minute] = (timePart || "").split(":").map(Number);

  if (
    [year, month, day, hour, minute].some(num => Number.isNaN(num)) ||
    !year || !month || !day
  ) {
    return "";
  }

  const date = new Date(year, month - 1, day, hour, minute, 0);
  if (Number.isNaN(date.getTime())) return "";

  return date.toISOString();
};

const toDateObject = value => {
  if (!value) return null;

  const [datePart, timePart = "00:00"] = value.split(" ");
  const [year, month, day] = (datePart || "").split("-").map(Number);
  const [hour, minute] = (timePart || "").split(":").map(Number);

  if ([year, month, day, hour, minute].some(num => Number.isNaN(num))) {
    return null;
  }

  const date = new Date(year, month - 1, day, hour, minute, 0);
  return Number.isNaN(date.getTime()) ? null : date;
};

// 仅接受有限整数，防止 1.5 等异常人数混入
const parseNumberOrNull = value => {
  if (value === null || value === undefined || value === "") return null;
  const number = Number(value);
  if (!Number.isFinite(number) || !Number.isInteger(number)) return null;
  return number;
};

const showErrorToast = message => {
  wx.showToast({
    title: message,
    icon: "none"
  });
};

const createEmptyGroup = () => ({
  groupName: "",
  groupStartTime: "",
  groupStartTimeDate: "",
  groupStartTimeClock: "",
  groupEndTime: "",
  groupEndTimeDate: "",
  groupEndTimeClock: "",
  groupRegistrationCount: "",
  remark: ""
});

const createEmptyField = () => ({
  fieldName: "",
  isOptional: false
});

const createInitialActivity = () => ({
  activityName: "",
  activityLocation: "",
  registrationStartTime: "",
  registrationStartTimeDate: "",
  registrationStartTimeClock: "",
  registrationEndTime: "",
  registrationEndTimeDate: "",
  registrationEndTimeClock: "",
  activityDetails: "",
  activityImageURL: "",
  activityRequirements: ""
});

const toDateValue = source => {
  if (!source) return null;

  if (source instanceof Date) {
    return Number.isNaN(source.getTime()) ? null : source;
  }

  if (typeof source === "object" && source.$date) {
    return toDateValue(source.$date);
  }

  let normalized = source;
  if (typeof source === "string") {
    normalized = source.trim();
    if (!normalized) return null;

    // 时间戳
    if (/^\d+$/.test(normalized)) {
      const timestamp = Number(normalized);
      return Number.isNaN(timestamp) ? null : new Date(timestamp);
    }

    // 兼容斜杠
    normalized = normalized.replace(/\//g, "-");

    // "YYYY-MM-DD HH:mm(:ss)" -> 用 T
    if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}(:\d{2})?$/.test(normalized)) {
      normalized = normalized.replace(" ", "T");
    }
    // "YYYY-MM-DDTHH:mm" -> 补秒
    if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(normalized)) {
      normalized = `${normalized}:00`;
    }
    // "YYYY-MM-DD" -> 补时间
    if (/^\d{4}-\d{2}-\d{2}$/.test(normalized)) {
      normalized = `${normalized}T00:00:00`;
    }
  }

  const result = new Date(normalized);
  return Number.isNaN(result.getTime()) ? null : result;
};

const toPickerParts = value => {
  const date = toDateValue(value);
  if (!date) {
    return { date: "", time: "" };
  }
  const year = date.getFullYear();
  const month = padTwoDigits(date.getMonth() + 1);
  const day = padTwoDigits(date.getDate());
  const hour = padTwoDigits(date.getHours());
  const minute = padTwoDigits(date.getMinutes());
  return {
    date: `${year}-${month}-${day}`,
    time: `${hour}:${minute}`
  };
};

const normalizeStatus = value => {
  if (value === null || value === undefined) return "Unknown";

  const mapping = {
    Draft: "Draft",
    draft: "Draft",
    Published: "Published",
    published: "Published",
    Withdraw: "Withdraw",
    withdraw: "Withdraw"
  };

  if (typeof value === "string") {
    const trimmed = value.trim();
    if (!trimmed) return "Unknown";
    if (/^\d+$/.test(trimmed)) {
      value = Number(trimmed);
    } else {
      const lower = trimmed.toLowerCase();
      if (mapping[trimmed]) return mapping[trimmed];
      if (mapping[lower]) return mapping[lower];
      if (lower === "withdrawn") return "Withdraw";
      return trimmed;
    }
  }

  if (typeof value === "number") {
    if (value === 1 || value === 0) return "Draft";
    if (value === 2) return "Published";
    if (value === 3) return "Withdraw";
    return "Unknown";
  }

  return typeof value === "string" ? value : "Unknown";
};

Page({
  data: {
    loading: true,
    activityID: "",
    activity: createInitialActivity(),
    activityFields: [],
    groups: [createEmptyGroup()],
    submitting: false,
    defaultDate: getCurrentDateString(),
    defaultTime: getCurrentTimeString(),
    currentStatus: "Draft"
  },

  onLoad(options = {}) {
    const activityID =
      options.activityID || options.activityId || options.id || "";

    this.setData({
      defaultDate: getCurrentDateString(),
      defaultTime: getCurrentTimeString()
    });

    if (!activityID) {
      showErrorToast("未提供活动编号");
      this.setData({ loading: false });
      return;
    }

    this.setData({ activityID, loading: true });
    this.loadActivityDetail(activityID);
  },

  onShow() {
    this.setData({
      defaultDate: getCurrentDateString(),
      defaultTime: getCurrentTimeString()
    });
  },

  loadActivityDetail(activityID) {
    callCloud({
      name: "queryActivityInfo",
      data: { activityID },
      loadingTitle: "加载中...",
      success: res => {
        const payload = res && (res.result || res.data || res);
        if (!payload || !payload.activityID) {
          showErrorToast("未获取到活动信息");
          this.setData({ loading: false });
          return;
        }
        this.applyActivityDetail(payload);
      },
      fail: err => {
        console.error("queryActivityInfo failed", err);
        showErrorToast("活动信息加载失败");
        this.setData({ loading: false });
      }
    });
  },

  applyActivityDetail(detail) {
    const status = normalizeStatus(detail.activityStatus);
    const activity = createInitialActivity();

    activity.activityName = detail.activityName || "";
    activity.activityLocation = detail.activityLocation || "";
    activity.activityDetails = detail.activityDetails || "";
    activity.activityImageURL = detail.activityImageURL || "";
    activity.activityRequirements = detail.activityRequirements || "";

    const registrationStartParts = toPickerParts(detail.registrationStartTime);
    activity.registrationStartTimeDate = registrationStartParts.date;
    activity.registrationStartTimeClock = registrationStartParts.time;
    activity.registrationStartTime = combineDateTime(
      registrationStartParts.date,
      registrationStartParts.time
    );

    const registrationEndParts = toPickerParts(detail.registrationEndTime);
    activity.registrationEndTimeDate = registrationEndParts.date;
    activity.registrationEndTimeClock = registrationEndParts.time;
    activity.registrationEndTime = combineDateTime(
      registrationEndParts.date,
      registrationEndParts.time
    );

    const groupsSource = Array.isArray(detail.activityGroups)
      ? detail.activityGroups
      : [];

    const groups =
      groupsSource.length > 0
        ? groupsSource.map(group => {
            const startParts = toPickerParts(group.groupStartTime);
            const endParts = toPickerParts(group.groupEndTime);
            return {
              groupName: group.groupName || "",
              groupStartTime: combineDateTime(startParts.date, startParts.time),
              groupStartTimeDate: startParts.date,
              groupStartTimeClock: startParts.time,
              groupEndTime: combineDateTime(endParts.date, endParts.time),
              groupEndTimeDate: endParts.date,
              groupEndTimeClock: endParts.time,
              groupRegistrationCount:
                typeof group.groupRegistrationCount === "number" ||
                typeof group.groupRegistrationCount === "string"
                  ? `${group.groupRegistrationCount}`
                  : "",
              remark: group.remark || ""
            };
          })
        : [createEmptyGroup()];

    const existingFields = Array.isArray(detail.activityFields)
      ? detail.activityFields.map(field => ({
          fieldName: field.fieldName || "",
          isOptional: !!field.isOptional
        }))
      : [];

    this.setData({
      activity,
      groups,
      activityFields: existingFields,
      currentStatus: status,
      loading: false
    });

    if (!existingFields.length) {
      this.loadActivityFields(detail.activityID);
    }
  },

  loadActivityFields(activityID) {
    callCloud({
      name: "queryActivityRegisterInfoCollection",
      data: { activityID },
      loadingTitle: "加载中...",
      success: res => {
        const payload = res && (res.result || res.data || res);
        const fields = Array.isArray(payload && payload.fields)
          ? payload.fields.map(field => ({
              fieldName: field.fieldName || "",
              isOptional: !!field.isOptional
            }))
          : [];
        if (fields.length > 0) {
          this.setData({ activityFields: fields });
        }
      },
      fail: err => {
        console.warn("queryActivityRegisterInfoCollection failed", err);
      }
    });
  },

  handleActivityInput(event) {
    const field = event.currentTarget.dataset.field;
    const value = event.detail.value;
    if (!field) return;
    this.setData({
      [`activity.${field}`]: value
    });
  },

  handleDateTimeChange(event) {
    const { field, part } = event.currentTarget.dataset;
    const value = event.detail.value;
    if (!field || !part) return;
    this.setData({
      [`activity.${field}${part === "date" ? "Date" : "Clock"}`]: value
    });
  },

  handleFieldInput(event) {
    const { index, field } = event.currentTarget.dataset;
    const value = event.detail.value;
    if (index === undefined || field !== "fieldName") return;
    this.setData({
      [`activityFields[${index}].fieldName`]: value
    });
  },

  handleFieldOptionalChange(event) {
    const { index } = event.currentTarget.dataset;
    if (index === undefined) return;
    this.setData({
      [`activityFields[${index}].isOptional`]: event.detail.value
    });
  },

  handleAddField() {
    const fields = this.data.activityFields.concat([createEmptyField()]);
    this.setData({ activityFields: fields });
  },

  handleRemoveField(event) {
    const index = event.currentTarget.dataset.index;
    if (index === undefined) return;
    const fields = this.data.activityFields.slice();
    fields.splice(index, 1);
    this.setData({ activityFields: fields });
  },

  handleAddGroup() {
    const groups = this.data.groups.concat([createEmptyGroup()]);
    this.setData({ groups });
  },

  handleRemoveGroup(event) {
    const index = event.currentTarget.dataset.index;
    if (index === undefined) return;
    if (this.data.groups.length <= 1) {
      showErrorToast("至少保留一个分组");
      return;
    }
    const groups = this.data.groups.slice();
    groups.splice(index, 1);
    this.setData({ groups });
  },

  handleGroupInput(event) {
    const { index, field } = event.currentTarget.dataset;
    const value = event.detail.value;
    if (index === undefined || !field) return;
    this.setData({
      [`groups[${index}].${field}`]: value
    });
  },

  handleGroupDateTimeChange(event) {
    const { index, field, part } = event.currentTarget.dataset;
    const value = event.detail.value;
    if (index === undefined || !field || !part) return;
    this.setData({
      [`groups[${index}].${field}${part === "date" ? "Date" : "Clock"}`]: value
    });
  },

  handleChooseImage() {
    wx.chooseImage({
      count: 1,
      sizeType: ["compressed"],
      sourceType: ["album", "camera"],
      success: res => {
        if (res.tempFilePaths && res.tempFilePaths.length > 0) {
          this.setData({
            "activity.activityImageURL": res.tempFilePaths[0]
          });
        }
      }
    });
  },

  handleRemoveImage() {
    this.setData({
      "activity.activityImageURL": ""
    });
  },

  handlePreviewImage() {
    const url = this.data.activity.activityImageURL;
    if (!url) return;
    wx.previewImage({ urls: [url] });
  },

  validateForPublish() {
    const { activity, groups, activityFields } = this.data;

    if (!activity.activityName.trim()) return "请填写活动名称";
    if (!activity.activityLocation.trim()) return "请填写活动地点";
    if (!activity.registrationStartTimeDate || !activity.registrationStartTimeClock) {
      return "请选择报名开始时间";
    }
    if (!activity.registrationEndTimeDate || !activity.registrationEndTimeClock) {
      return "请选择报名结束时间";
    }

    const registrationStartValue = combineDateTime(
      activity.registrationStartTimeDate,
      activity.registrationStartTimeClock
    );
    const registrationEndValue = combineDateTime(
      activity.registrationEndTimeDate,
      activity.registrationEndTimeClock
    );
    const registrationStart = toDateObject(registrationStartValue);
    const registrationEnd = toDateObject(registrationEndValue);

    if (!registrationStart || !registrationEnd) return "报名时间格式不正确";
    if (registrationStart.getTime() > registrationEnd.getTime()) {
      return "报名结束时间需晚于开始时间";
    }

    if (!activity.activityDetails.trim()) return "请填写活动详细介绍";
    if (!activity.activityImageURL) return "请上传活动图片";
    if (!activity.activityRequirements.trim()) return "请填写活动要求";
    if (!groups || groups.length === 0) return "请至少保留一个活动分组";

    const groupNames = new Set();
    for (let i = 0; i < groups.length; i += 1) {
      const group = groups[i];
      const displayIndex = i + 1;

      if (!group.groupName.trim()) return `请填写第 ${displayIndex} 个分组的名称`;
      const nameKey = group.groupName.trim();
      if (groupNames.has(nameKey)) return `分组名称重复：${nameKey}`;
      groupNames.add(nameKey);

      if (!group.groupStartTimeDate || !group.groupStartTimeClock) {
        return `请选择第 ${displayIndex} 个分组的开始时间`;
      }
      if (!group.groupEndTimeDate || !group.groupEndTimeClock) {
        return `请选择第 ${displayIndex} 个分组的结束时间`;
      }

      const startValue = combineDateTime(group.groupStartTimeDate, group.groupStartTimeClock);
      const endValue = combineDateTime(group.groupEndTimeDate, group.groupEndTimeClock);
      const startDate = toDateObject(startValue);
      const endDate = toDateObject(endValue);

      if (!startDate || !endDate) return `第 ${displayIndex} 个分组的时间格式不正确`;
      if (startDate.getTime() > endDate.getTime()) {
        return `第 ${displayIndex} 个分组的结束时间需晚于开始时间`;
      }

      const countValue = parseNumberOrNull(group.groupRegistrationCount);
      if (countValue === null || countValue <= 0) {
        return `请填写第 ${displayIndex} 个分组的有效报名人数上限`;
      }
    }

    if (activityFields.length > 0) {
      const fieldNames = [];
      for (let i = 0; i < activityFields.length; i += 1) {
        const field = activityFields[i];
        const trimmedName = (field.fieldName || "").trim();
        if (!trimmedName) return `请填写第 ${i + 1} 个报名问题的名称`;
        if (fieldNames.includes(trimmedName)) return `报名问题重复：${trimmedName}`;
        fieldNames.push(trimmedName);
      }
    }

    return "";
  },

  buildPayload(status) {
    const { activityID, activity, groups, activityFields } = this.data;
    if (!activityID) {
      showErrorToast("未找到活动编号");
      return null;
    }

    const registrationStart = combineDateTime(
      activity.registrationStartTimeDate,
      activity.registrationStartTimeClock
    );
    const registrationEnd = combineDateTime(
      activity.registrationEndTimeDate,
      activity.registrationEndTimeClock
    );

    const payload = {
      activityID,
      activityName: activity.activityName.trim(),
      activityLocation: activity.activityLocation.trim(),
      activityDetails: activity.activityDetails.trim(),
      activityImageURL: activity.activityImageURL,
      activityRequirements: activity.activityRequirements.trim(),
      activityStatus: status,
      activityGroups: groups.map(group => {
        const start = combineDateTime(group.groupStartTimeDate, group.groupStartTimeClock);
        const end = combineDateTime(group.groupEndTimeDate, group.groupEndTimeClock);
        const count = parseNumberOrNull(group.groupRegistrationCount);
        const formatted = {
          groupName: group.groupName.trim(),
          remark: (group.remark || "").trim()
        };

        const startISO = toISOStringString(start);
        if (start && startISO) formatted.groupStartTime = startISO;

        const endISO = toISOStringString(end);
        if (end && endISO) formatted.groupEndTime = endISO;

        if (count !== null) formatted.groupRegistrationCount = count;

        return formatted;
      }),
      activityFields: activityFields.map(field => ({
        fieldName: (field.fieldName || "").trim(),
        isOptional: !!field.isOptional
      }))
    };

    const startISO = toISOStringString(registrationStart);
    if (registrationStart && startISO) payload.registrationStartTime = startISO;

    const endISO = toISOStringString(registrationEnd);
    if (registrationEnd && endISO) payload.registrationEndTime = endISO;

    return payload;
  },

  handleSubmit(event) {
    const dataset = (event && event.currentTarget && event.currentTarget.dataset) || {};
    const status = dataset.status;
    if (!status || this.data.submitting) return;

    if (this.data.currentStatus === "Published" && status === "Draft") {
      showErrorToast("已发布活动不可保存为草稿");
      return;
    }

    if (status === "Published") {
      const validationMessage = this.validateForPublish();
      if (validationMessage) {
        showErrorToast(validationMessage);
        return;
      }
    }

    const payload = this.buildPayload(status);
    if (!payload) return;

    this.setData({ submitting: true });

    callCloud({
      name: "alterActivityInfo",
      data: payload,
      loadingTitle: "提交中...",
      success: res => {
        const result = res && res.result ? res.result : res;
        if (result && result.success) {
          const successText =
            status === "Published"
              ? "保存成功"
              : status === "Withdraw"
              ? "已撤销"
              : "已保存";
          wx.showToast({ title: successText, icon: "success" });
          this.setData({ currentStatus: status });
          setTimeout(() => {
            this.navigateAfterEditSubmit();
          }, 800);
        } else {
          showErrorToast((result && result.error) || "操作失败，请稍后重试");
        }
      },
      fail: err => {
        console.error("alterActivityInfo failed", err);
        showErrorToast("提交失败，请稍后重试");
      },
      complete: () => {
        this.setData({ submitting: false });
      }
    });
  },

  handleWithdrawTap() {
    if (this.data.submitting) return;
    wx.showModal({
      title: "撤销活动",
      content: "撤销后活动将不再接受报名，确认继续？",
      confirmText: "确认撤销",
      cancelText: "取消",
      success: res => {
        if (res && res.confirm) {
          this.handleSubmit({
            currentTarget: { dataset: { status: "Withdraw" } }
          });
        }
      }
    });
  },

  navigateAfterEditSubmit() {
    const pages = typeof getCurrentPages === "function" ? getCurrentPages() : [];
    if (pages && pages.length > 1) {
      wx.navigateBack({ delta: 1 });
      return;
    }
    const activityID =
      this.data && this.data.activityID ? String(this.data.activityID).trim() : "";
    if (activityID) {
      wx.reLaunch({
        url: `/pages/activity-detail/activity-detail?activityID=${encodeURIComponent(
          activityID
        )}`
      });
      return;
    }
    wx.reLaunch({ url: "/pages/home/home" });
  }
});
